package jvm.autoMemoryManagement;

/**
 * VM Args: -Xss128k
 * @author msi
 * 验证HotSpot不允许栈动态扩展
 * 行为： 1.使用 -Xss 参数减少栈内存容量
 *          结果：抛出StackOverFlowError，并且栈深度相应减少
 *       2.定义大量的本地内存，曾大此方法栈中本地变量表的长度
 *          结果：抛出StackOverFlowError，并且栈深度相应减少
 * 结论：在HotSpot虚拟机中可见不会抛出OutOfMemoryError异常。但是如果在Classic(允许栈动态扩展)虚拟机中允许行为2，则会抛出OOM
 *      只有一种例外HotSpot也会抛出OOM，见片段3.
 */
public class JavaVMStackSOF {
    /* 行为1
    private int stackLength=1;

    public void stackLeak(){
        stackLength++;
        stackLeak();
    }

    public static void main(String args[]){
        JavaVMStackSOF javaVMStackSOF = new JavaVMStackSOF();

        try {
            javaVMStackSOF.stackLeak();
        } catch (Throwable e) {
            System.out.println("stack length: "+javaVMStackSOF.stackLength);
            throw e;
        }
    }
    //
    // 结果当 -Xss 128k时  stack length: 1540  抛出java.lang.StackOverflowError
    //    当 -Xss 256k时  stack length: 3460  抛出java.lang.StackOverflowError
    //
    */


    /*
    //行为2
    private int stackLength=1;

    public void stackLeak(){
        long unused1,unused2,unused3,unused4,unused5,unused6,unused7,unused8,unused9,unused10;
        stackLength++;
        stackLeak();
        unused1=unused2=unused3=unused4=unused5=unused6=unused7=unused8=unused9=unused10=0;
    }

    public static void main(String args[]){
        JavaVMStackSOF javaVMStackSOF = new JavaVMStackSOF();

        try {
            javaVMStackSOF.stackLeak();
        } catch (Throwable e) {
            System.out.println("stack length: "+javaVMStackSOF.stackLength);
            throw e;
        }
    }
    //
    // 结果当 -Xss 128k时  stack length: 335  抛出java.lang.StackOverflowError
    //    当 -Xss 256k时  stack length: 1356  抛出java.lang.StackOverflowError
    //

     */

    //片段3.HotSpot虚拟机抛出OOM，没有亲自尝试过。根据书中提示，在window系统中执行该代码有很高的风险。可能会导致操作系统假死
    //原理，通过无限制的创建线程，从而导致电脑内存崩溃

    private void dontStop(){
        while(true){

        }
    }

    public void stackLeakByThread(){
        while (true){
            Thread thread = new Thread(new Runnable() {
                @Override
                public void run() {
                    dontStop();
                }
            });
            thread.start();
        }
    }

    public static void main(String[] args) {
        JavaVMStackSOF javaVMStackSOF = new JavaVMStackSOF();
        javaVMStackSOF.stackLeakByThread();
    }

    //结果: java.lang.OutOfMemoryError: unable to create native thread.
}
